use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use serde_json::Result;

use crate::MonResult;

/// 控制协议输出类型
///
/// 内部是 `HashMap`, 具体键值由命令自行决定
pub type Protocol = HashMap<String, String>;

/// 默认的 smp 控制协议返回
///
/// 当不需要向调用者返回任何数据时, 使用该函数快速返回结果
#[allow(clippy::missing_errors_doc)]
pub fn protocol_ok() -> MonResult<Protocol> {
    Ok(HashMap::new())
}

#[derive(Serialize, Deserialize)]
pub(crate) struct MonitorProtocolResult {
    result: MonResult<Protocol>,
}

impl MonitorProtocolResult {
    pub(crate) fn new(result: MonResult<Protocol>) -> Self {
        Self { result }
    }

    pub(crate) fn to_json(&self) -> String {
        serde_json::to_string(self).unwrap()
    }
}

#[derive(Serialize, Deserialize)]
pub(crate) struct MonitorProtocol {
    command: String,
    args: Protocol,
}

impl MonitorProtocol {
    pub(crate) fn new(command: &str, args: &Protocol) -> Self {
        MonitorProtocol { command: command.to_string(), args: args.clone() }
    }

    pub(crate) fn from_json(json: &str) -> Result<Self> {
        serde_json::from_str(json)
    }

    pub(crate) fn to_json(&self) -> String {
        serde_json::to_string(self).unwrap()
    }

    #[inline]
    pub(crate) fn command(&self) -> &String {
        &self.command
    }

    #[inline]
    pub(crate) fn args(&self) -> &Protocol {
        &self.args
    }
}
